package com.hzhq.contract.controller;

import com.hzhq.contract.bean.dto.ContractTypeDTO;
import com.hzhq.contract.bean.entity.ContractType;
import com.hzhq.contract.bean.entity.User;
import com.hzhq.contract.bean.vo.ContractTypeVO;
import com.hzhq.contract.convert.ContractTypeConvertBasic;
import com.hzhq.contract.result.Result;
import com.hzhq.contract.service.AttachmentService;
import com.hzhq.contract.service.ContractService;
import com.hzhq.contract.service.ContractTypeService;
import com.hzhq.contract.service.TemplateService;
import com.hzhq.contract.status.DefaultValue;
import com.hzhq.contract.util.Page2ResultUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: hzhq1255
 * @mail: hzhq1255@163.com
 * @date: 2021/4/20 23:46
 * @desc:
 */
@Slf4j
@Api(tags = "合同类别管理")
@CrossOrigin
@RestController
@ResponseBody
@RequestMapping("/api/v1/contracts/types")
public class ContractTypeController {
    @Autowired
    ContractTypeService typeService;

    @Autowired
    ContractService contractService;

    @Autowired
    AttachmentService attachmentService;

    @Autowired
    TemplateService templateService;

    @ApiOperation("getAllTypeList")
    @ResponseBody
    @RequestMapping(method = RequestMethod.GET)
    private Result<Object> getAllTypeList() {
        List<ContractTypeVO> typeVOList = typeService.getAllList().stream().map(ContractTypeConvertBasic.INSTANCE::dtoToVo).collect(Collectors.toList());
        return Result.success(typeVOList);
    }

    @ApiOperation("getAllTypePage")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "currentPage", value = "当前页", example = "1", paramType = "path", dataTypeClass = Integer.class, dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "个数", example = "10", paramType = "path", dataTypeClass = Integer.class, dataType = "Integer")
    })
    @ResponseBody
    @RequestMapping(value = "/currentPage/{currentPage}/pageSize/{pageSize}", method = RequestMethod.GET)
    private Result<Object> getAllTypePage(@PathVariable("currentPage") @NotNull Integer currentPage,
                                          @PathVariable("pageSize") @NotNull Integer pageSize) {
        Page<ContractTypeVO> typeVOS = typeService.getAllPage(currentPage, pageSize).map(ContractTypeConvertBasic.INSTANCE::dtoToVo);
        return Result.success(Page2ResultUtil.getPageData(typeVOS));
    }

    @ApiOperation("getAllTypePage")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "currentPage", value = "当前页", example = "1", paramType = "path", dataTypeClass = Integer.class, dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "个数", example = "10", paramType = "path", dataTypeClass = Integer.class, dataType = "Integer")
    })
    @ResponseBody
    @RequestMapping(value = "/search/query/currentPage/{currentPage}/pageSize/{pageSize}", method = RequestMethod.GET)
    private Result<Object> searchAllPageByQuery(@PathVariable("currentPage") @NotNull Integer currentPage,
                                                @PathVariable("pageSize") @NotNull Integer pageSize,
                                                @RequestParam(value = "typeName",required = false) String typeName) {
        final Query query = new Query();
        final Criteria criteria = new Criteria();
        List<Criteria> ands = new ArrayList<>();
        List<Criteria> ors = new ArrayList<>();
        if (typeName != null){
            ors.add(Criteria.where(ContractType.TYPE_NAME_FIELD).regex("^.*"+typeName+".*$"));
            criteria.orOperator(ors.toArray(Criteria[]::new));
        }
        ands.add(Criteria.where(ContractType.DELETED_FIELD).is(DefaultValue.NOT_DELETED));
        criteria.andOperator(ands.toArray(Criteria[]::new));
        query.addCriteria(criteria);
        Page<ContractTypeVO> typeVOS = typeService.searchAllPageByQuery(query,currentPage, pageSize).map(ContractTypeConvertBasic.INSTANCE::dtoToVo);
        return Result.success(Page2ResultUtil.getPageData(typeVOS));
    }


    @ApiOperation("getTypeById")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", paramType = "path", dataType = "String", dataTypeClass = String.class)
    })
    @ResponseBody
    @RequestMapping(value = "/id/{id}", method = RequestMethod.GET)
    private Result<Object> getTypeById(@PathVariable("id") @NotNull String id) {
        if (!ObjectId.isValid(id)) {
            return Result.error("typeId=" + id + " is not valid!");
        }
        ContractTypeVO typeVO = ContractTypeConvertBasic.INSTANCE.dtoToVo(typeService.getOneById(id));
        if (typeVO == null) {
            return Result.error("typeId=" + id + " is not existed!");
        }
        return Result.success(typeVO);
    }

    @ApiOperation("getTypeByName")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "name", paramType = "path", dataType = "String", dataTypeClass = String.class)
    })
    @ResponseBody
    @RequestMapping(value = "/name/{name}", method = RequestMethod.GET)
    private Result<Object> getTypeByName(@PathVariable("name") @NotNull String name) {
        ContractTypeVO typeVO = ContractTypeConvertBasic.INSTANCE.dtoToVo(typeService.getOneByName(name));
        if (typeVO == null) {
            return Result.error("typeName=" + name + " is not existed!");
        }
        return Result.success(typeVO);
    }

    @ApiOperation("getTypeByCode")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "code", paramType = "path", dataType = "Integer", dataTypeClass = Integer.class)
    })
    @ResponseBody
    @RequestMapping(value = "/code/{code}", method = RequestMethod.GET)
    private Result<Object> getTypeByCode(@PathVariable("code") @NotNull Integer code) {
        ContractTypeVO typeVO = ContractTypeConvertBasic.INSTANCE.dtoToVo(typeService.getOneByCode(code));
        if (typeVO == null) {
            return Result.error("typeName=" + code + " is not existed!");
        }
        return Result.success(typeVO);
    }

    @ApiOperation("deleteTypeById")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", paramType = "path", dataType = "String", dataTypeClass = String.class)
    })
    @ResponseBody
    @RequestMapping(value = "/delete/id/{id}", method = RequestMethod.POST)
    private Result<Object> deleteTypeById(@PathVariable("id") @NotNull String id) {
        if (!ObjectId.isValid(id)) {
            return Result.error("typeId=" + id + " is not valid!");
        }
        String deleteId = typeService.deleteById(id);
        if (deleteId == null) {
            return Result.error("typeId=" + id + " is not existed!");
        }
        return Result.success(deleteId);
    }

    @ApiOperation("typeSave")
    @ResponseBody
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    private Result<Object> typeSave(@RequestBody @NotNull ContractTypeDTO typeDTO) {
        if (typeService.getOneByName(typeDTO.getTypeName()) != null) {
            return Result.error(typeDTO.getTypeName() + " 已存在!");
        }
        typeDTO.setDeleted(DefaultValue.NOT_DELETED);
        ContractTypeDTO type = typeService.save(typeDTO);
        if (type == null) {
            return Result.error("保存失败");
        }
        return Result.success(type.getTypeId().toString());
    }

    @ApiOperation("typeUpdate")
    @ResponseBody
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    private Result<Object> typeUpdate(@RequestBody @NotNull ContractTypeVO typeVO) {
        if (!ObjectId.isValid(typeVO.getTypeId())) {
            return Result.error("typeId=" + typeVO.getTypeId() + " is not valid!");
        }
        if (typeService.getOneByName(typeVO.getTypeName()) == null) {
            return Result.error(typeVO.getTypeName() + " is not existed!");
        }
        ContractTypeDTO type = typeService.save(ContractTypeConvertBasic.INSTANCE.voToDto(typeVO));
        if (type == null) {
            return Result.error(" update failure");
        }
        return Result.success(type.getTypeId().toString());
    }

}
